home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GAMES
/
WIMPGAME
/
MINES2.ZIP
/
!Mines
/
c
/
bench
next >
Wrap
Text File
|
1995-01-28
|
25KB
|
860 lines
/* Benchmarking und "Uberpr"ufung der
** Optimierungen
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#define MINE 1 /* Flags für die Felder */
#define MARK 2
#define CLOSED 4
#define XMAX 30
#define YMAX 16
#define FALSE 0
#define TRUE 1
int feld[XMAX][YMAX] ; /* DAS Spielfeld */
int mines_left,fields_left; /* Zähler Variable */
/* Richtungen zum Suchen */
int off[8][2] = { {-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};
/* Benchmarkanalysis */
int freq_o[256]; /* frequency of domain of n elements without division */
int steps_o[256]; /* ... */
int freq[256]; /* Frequency of domain of n elements */
int steps[256]; /* Sum of number of steps for a n-element-domain */
int time_c,time_a; /* Time in centiseconds of calulation ( with assemlbly ) */
int s;
int ende,err,overflow;
#define OBVIOUS 1
#define HINT_DEBUG 2
#define MARK_SET 3
#define NO_MINE 4
#define MINES_LEFT 5
#define NEG_REST_FIELDS 6
#define WRONG 7
#define NOT_CLOSED 8
#define UNKNOWN 255
/* Feder initialisieren (feld,bottom,vlines,lines)*/
void res_feld()
{int i,j ;
div_t r ;
mines_left=120;
fields_left = XMAX*YMAX-mines_left ;/* Freie Felder */
for( i = 0 ; i < XMAX ; i++ ) /* alle Felder ohne Mienen und geschlossen */
for( j = 0 ; j < YMAX ; j++ )
feld[ i ][ j ] = CLOSED ;
for( i=0 ; i<mines_left ;i++) /* jetzt ein paar Minen legen */
{do{r = div( rand() , XMAX ) ;
j = r.rem ;
r = div( rand() , YMAX ) ;
}while(feld[j][r.rem] & MINE) ;
feld[j][r.rem] |= MINE ;
}
}
/* Anzahl der Minen um ein Feld zählen */
int count(int x,int y)
{int i,c=0,x1,y1 ;
for(i=0 ; i<8 ; i++)
{x1 = x+off[i][0] ;
y1 = y+off[i][1] ;
if(x1>=0 && x1<XMAX && y1>=0 && y1<YMAX)
if(feld[x1][y1] & MINE)
c++ ;
}
return c ;
}
/* Ein Feld (gegebenenfalls mehrere rekursiv) oeffnen */
void open_field(int x,int y)
{int i ;
if(x>=0 && x<XMAX && y>=0 && y<YMAX && (feld[x][y] & CLOSED))
{
feld[x][y] &= ~CLOSED ;
fields_left-- ;
if(count(x,y) == 0)
{for(i=0;i<8;i++)
if( (feld[x+off[i][0]][y+off[i][1]] & CLOSED)
&& !(feld[x+off[i][0]][y+off[i][1]] & MARK))
open_field(x+off[i][0],y+off[i][1]) ;
}
}
}
void blotch(void)
{int x,y,min,x1,y1;
int i,j,k,l,h ;
x = XMAX/2 ;
y = YMAX/2 ;
min = 9 ;
if(XMAX>YMAX)
j = x ;
else
j = y ;
if(x>=0 && x<XMAX && y>=0 && y<YMAX)
{if( !(feld[x][y] & MINE) && (feld[x][y] & CLOSED) )
{x1 = x ;
y1 = y ;
min = count(x,y) ;
}
}
x-- ;
y-- ;
for(i=1;i<=j;i++)
{for(l=0 ; l<4 ; l++)
{k = 2 * i + 1 ;
do{if(x>=0 && x<XMAX && y>=0 && y<YMAX)
{if( !(feld[x][y] & MINE) && (feld[x][y] & CLOSED) )
{h = count(x,y) ;
if(h<min)
{x1 = x ;
y1 = y ;
min = h ;
}
}
}
k-- ;
if(k>0)
{switch(l)
{case 0:
x++ ;
break ;
case 1:
y++ ;
break ;
case 2:
x-- ;
break ;
case 3:
y-- ;
break ;
}
}
}while(k>0) ;
}
x-- ;
y-- ;
}
if(min!=9)
open_field(x1,y1) ;
}
#define in_playground(x,y) (((x)>=0) && ((x)<XMAX) && ((y)>=0) && ((y)<YMAX))
int move_wrong(int x0,int y0)
{
return ((feld[x0][y0] & MARK) && !(feld[x0][y0] & MINE));
}
int move_obvious(int x0,int y0)
{
int mines=0,marks=0,unknown=0,d;
if (feld[x0][y0] & CLOSED) return(FALSE);
for (d=0;d<8;d++)
{
int x1=x0+off[d][0],y1=y0+off[d][1];
if (in_playground(x1,y1))
{
register char f=feld[x1][y1];
if (f & CLOSED) {if (f & MARK) marks++; else unknown++;};
if (f & MINE) mines++;
}
}
if ((unknown!=0) && ((marks==mines) || (marks+unknown==mines))) return(TRUE);
return(FALSE);
}
typedef struct {char x,y,test,domain;} border_typ;
border_typ *border_arr,*border_anz,*last_border_arr=0,*last_border_anz;
int *minmax=0,*lastminmax=0;
#include "HintA.h"
#define min(domain) minmax[(domain)*2]
#define max(domain) minmax[(domain)*2+1]
#define last_min(last_domain) lastminmax[(last_domain)*2]
#define last_max(last_domain) lastminmax[(last_domain)*2+1]
int find_next(int *x,int *y)
{
/*
** sucht das naechste Feld, dass sowohl bedeckte als auch unbedeckte
** Felder als Nachbarn hat und selbst bedeckt ist, aber keine Marke
** hat.
*/
int closed_neighbors,open_neighbors,d;
do {
open_neighbors=0;closed_neighbors=0;
*x+=1;if (*x>=XMAX) {*x=0;*y+=1;};
if (*y<YMAX)
for (d=0;d<8;d++)
{
int newx=*x+off[d][0],newy=*y+off[d][1];
if (in_playground(newx,newy))
{if (feld[newx][newy] & CLOSED) closed_neighbors++;
else open_neighbors++;};
}
} while ((*y<YMAX) && ((feld[*x][*y] & MARK) || !(feld[*x][*y] & CLOSED) || (open_neighbors==0) || (closed_neighbors==0)));
if (*y>=YMAX) return FALSE;
return TRUE;
}
border_typ *find_field(int x,int y,border_typ *i)
{
while ((i<border_anz) && ((i->x!=x) || (i->y!=y))) i++;
if ((x==i->x) && (y==i->y) && (i<border_anz)) return i;
return 0;
}
border_typ *exchange_field(border_typ *end_domain,border_typ *i,char domain)
{
border_typ d;
if (i==0) return end_domain;
end_domain++;
d=*end_domain;*end_domain=*i;*i=d;
end_domain->domain=domain;
return end_domain;
}
border_typ *find_neighbors(int x0,int y0,border_typ *end_domain,char domain)
{
char d;
for (d=0;d<8;d++)
end_domain=exchange_field(end_domain,
find_field(x0+off[d][0],y0+off[d][1],end_domain+1),
domain);
return end_domain;
}
void find_domains(border_typ *border,char domain)
{
/*
** Sortiert border_arr in unabhaengige Gebiete, die durch
** ein (0,YMAX) getrennt sind
*/
char d;
border_typ *end_domain=border;
border->domain=domain;
do {
for (d=0;d<8;d++)
{
int x=border->x+off[d][0];
int y=border->y+off[d][1];
if (in_playground(x,y) && !(feld[x][y] & CLOSED))
end_domain=find_neighbors(x,y,end_domain,domain);
}
border++;
} while ((border->domain==domain) && (border<border_anz));
}
void find_testmode(border_typ *border,char domain)
{
while ((border->domain==domain) && (border<border_anz))
{
border_typ *ptr=border+1;
char x,y;
x=border->x;y=border->y;border->test=0;
while ((ptr->domain==domain) && (ptr<border_anz))
{
char x1=ptr->x,y1=ptr->y;
if (y1+2==y)
{
if (x1+2==x) border->test|=1;
if (x1+1==x) border->test|=1+2;
if (x1==x) border->test|=1+2+4;
if (x1==x+1) border->test|=2+4;
if (x1==x+2) border->test|=4;
}
if (y1+1==y)
{
if (x1+2==x) border->test|=1+8;
if (x1+1==x) border->test|=1+2+8;
if (x1==x) border->test|=1+2+4+8+16;
if (x1==x+1) border->test|=2+4+16;
if (x1==x+2) border->test|=4+16;
}
if (y1==y)
{
if (x1+2==x) border->test|=1+8+32;
if (x1+1==x) border->test|=1+2+8+32+64;
if (x1==x+1) border->test|=2+4+16+64+128;
if (x1==x+2) border->test|=4+16+128;
}
if (y1==y+1)
{
if (x1+2==x) border->test|=8+32;
if (x1+1==x) border->test|=8+32+64;
if (x1==x) border->test|=8+16+32+64+128;
if (x1==x+1) border->test|=16+64+128;
if (x1==x+2) border->test|=16+128;
}
if (y1==y+2)
{
if (x1+2==x) border->test|=32;
if (x1+1==x) border->test|=32+64;
if (x1==x) border->test|=32+64+128;
if (x1==x+1) border->test|=64+128;
if (x1==x+2) border->test|=128;
}
ptr++;
} /* while (ptr->domain==domain) */
border++;
} /* while (border->domain==domain) */
}
FILE *f;
char find_last_domain(border_typ *border)
{
border_typ *ptr=last_border_arr;
while ((ptr<last_border_anz) &&
((border->x!=ptr->x) || (border->y!=ptr->y)))
ptr++;
if (ptr>=last_border_anz) return 0;
return ptr->domain;
}
char find_new_domain(border_typ *last_border)
{
border_typ *ptr=border_arr;
while ((ptr<border_anz) &&
((last_border->x!=ptr->x) || (last_border->y!=ptr->y)))
ptr++;
if (ptr>=border_anz) return 0;
return ptr->domain;
}
void look_for_old_domain(border_typ *border,char domain)
{
border_typ *ptr,*border2=border;
char last_domain;
if (last_border_arr==0) return;
if ((last_domain=find_last_domain(border2))==0) return;
do { border2++;
} while ((border2<border_anz) && (border2->domain==domain) &&
(last_domain==find_last_domain(border2)));
if ((border2<border_anz) && (border2->domain==domain)) return;
ptr=last_border_arr;
while ((ptr->domain!=last_domain) && (ptr<last_border_anz)) ptr++;
if (ptr>=last_border_anz) return;
while ((ptr<last_border_anz) && (ptr->domain==last_domain) &&
(domain==find_new_domain(ptr)))
ptr++;
if ((ptr<last_border_anz) && (ptr->domain==last_domain)) return;
min(domain)=last_min(last_domain);
max(domain)=last_max(last_domain);
}
void werr(int x,char *s)
{ printf("%s\n",s);if (x) exit(1);err=UNKNOWN;ende=TRUE;return;}
void init_border()
{
border_typ *border;
int x,y;
char domain;
/*border_arr=malloc((XMAX*YMAX+1)*sizeof(border_typ));*/
border_anz=border_arr;x=-1;y=0;
if (border_arr==0) {werr(TRUE,"Could not allocate memory");return;};
while (find_next(&x,&y)) /* create border list */
{
border_anz->x=x;border_anz->y=y;border_anz->domain=0;
border_anz++;
}
if (border_anz==border_arr) return;
domain=1;border=border_arr; /* sort border list in domains */
do {
if (border<border_anz) find_domains(border,domain);
while ((border->domain==domain) && (border<border_anz)) border++;
domain++;
} while (border<border_anz);
/*x=border_anz-border_arr;
border_arr=realloc(border_arr,x*sizeof(border_typ));
if (border_arr==NULL)
{border_anz=border_arr;werr(FALSE,"Could not move memory");return;};
border_anz=border_arr+x;*/
for (border=border_arr;border<border_anz;border++)
if (feld[border->x][border->y] & MARK) werr(FALSE,"Mine found");
minmax=malloc(2*sizeof(int)*domain);
for (x=1;x<domain;x++) {min(x)=INT_MAX;max(x)=INT_MIN;};
domain=1;border=border_arr;
do {
if (border<border_anz) look_for_old_domain(border,domain);
while ((border->domain==domain) && (border<border_anz)) border++;
domain++;
} while (border<border_anz);
domain=1;border=border_arr; /* calculate the testmodes */
do {
if (border<border_anz) find_testmode(border,domain);
while ((border->domain==domain) && (border<border_anz)) border++;
domain++;
} while (border<border_anz);
}
#define h_MASK 192
#define h_EVERYTHING 0
#define h_NOMINE 64
#define h_MINE 128
#define h_UNKNOWN 192
void exit_border()
{
/*border_typ *border;
for (border=border_arr;border<border_anz;border++)
feld[border->x][border->y]&=~h_MASK;*/
/*if (last_border_arr!=0) {free(last_border_arr);free(lastminmax);};*/
border_typ *b=last_border_arr;int *i=lastminmax;
last_border_arr=border_arr;last_border_anz=border_anz;
border_arr=b;
lastminmax=minmax;minmax=i;
}
int otest_if_possible(border_typ *border_ptr)
{
/* Testet, ob die Wahl dieses Feldes gegen Informationen
der Nachbarfelder verstoesst */
char d0,d1,mines,marks,x1,y1;
for (d0=0;d0<8;d0++)
{
x1=border_ptr->x+off[d0][0];
y1=border_ptr->y+off[d0][1];
if (in_playground(x1,y1) && !(feld[x1][y1] & CLOSED))
{
mines=0;marks=0;
for (d1=0;d1<8;d1++)
{
char x2=x1+off[d1][0],y2=y1+off[d1][1];
if (in_playground(x2,y2))
{
register char f=feld[x2][y2];
if (f & MINE) mines++;
if (f & MARK) marks++;
}
}
if ((border_ptr->test & (1 << d0))!=0)
{ if (marks>mines) return FALSE; }
else { if (marks!=mines) return FALSE; }
}
}
return(TRUE);
}
#define p_POSSIBLE TRUE
#define p_IMPOSSIBLE FALSE
char permutate1(border_typ *border,int mine_anz,char domain)
{
char x,y;
char p1=p_IMPOSSIBLE,p2=p_IMPOSSIBLE,f1,f2;
s+=1;
if ((border->domain!=domain) || (border>=border_anz))
{
if (mine_anz>max(domain)) max(domain)=mine_anz;
if (mine_anz<min(domain)) min(domain)=mine_anz;
return p_POSSIBLE;
}
x=border->x;y=border->y;
if (otest_if_possible(border)) p1=permutate1(border+1,mine_anz,domain);
feld[x][y]|=MARK;
if (otest_if_possible(border)) p2=permutate1(border+1,mine_anz+1,domain);
feld[x][y]&=~MARK;
f1=feld[x][y] & h_MASK;f2=feld[x][y] & ~h_MASK;
if (p1==p_POSSIBLE)
{
if ((f1==h_NOMINE) || (f1==h_EVERYTHING)) f1=h_NOMINE;
else f1=h_UNKNOWN;
}
if (p2==p_POSSIBLE)
{
if ((f1==h_MINE) || (f1==h_EVERYTHING)) f1=h_MINE;
else f1=h_UNKNOWN;
}
feld[x][y]=f2 | f1;
/*if (f1==h_UNKNOWN)*/ return(p1 | p2);
}
char permutate2(border_typ *border,int mine_anz)
{
char x,y;
char p1=p_IMPOSSIBLE,p2=p_IMPOSSIBLE,f1,f2;
s+=1;
if (border>=border_anz)
{
if (mines_left+fields_left-(border_anz-border_arr)>=mine_anz)
return p_POSSIBLE; else return p_IMPOSSIBLE;
}
x=border->x;y=border->y;
if (otest_if_possible(border))
p1=permutate2(border+1,mine_anz);
if (mine_anz>0)
{
feld[x][y]|=MARK;
if (otest_if_possible(border)) p2=permutate2(border+1,mine_anz-1);
feld[x][y]&=~MARK;
}
f1=feld[x][y] & h_MASK;f2=feld[x][y] & ~h_MASK;
if (p1==p_POSSIBLE)
{
if ((f1==h_NOMINE) || (f1==h_EVERYTHING)) f1=h_NOMINE;
else f1=h_UNKNOWN;
}
if (p2==p_POSSIBLE)
{
if ((f1==h_MINE) || (f1==h_EVERYTHING)) f1=h_MINE;
else f1=h_UNKNOWN;
}
feld[x][y]=f2 | f1;
/*if (f1==h_UNKNOWN)*/ return(p1 | p2);
}
char apermutate1(border_typ *border,int mine_anz,char domain)
{
char x,y;
char p1=p_IMPOSSIBLE,p2=p_IMPOSSIBLE,f1,f2;
if ((border->domain!=domain) || (border>=border_anz))
{
if (mine_anz>max(domain)) max(domain)=mine_anz;
if (mine_anz<min(domain)) min(domain)=mine_anz;
return p_POSSIBLE;
}
x=border->x;y=border->y;
if (test_if_possible(border,XMAX,YMAX,feld)) p1=apermutate1(border+1,mine_anz,domain);
feld[x][y]|=MARK;
if (test_if_possible(border,XMAX,YMAX,feld)) p2=apermutate1(border+1,mine_anz+1,domain);
feld[x][y]&=~MARK;
f1=feld[x][y] & h_MASK;f2=feld[x][y] & ~h_MASK;
if (p1==p_POSSIBLE)
{
if ((f1==h_NOMINE) || (f1==h_EVERYTHING)) f1=h_NOMINE;
else f1=h_UNKNOWN;
}
if (p2==p_POSSIBLE)
{
if ((f1==h_MINE) || (f1==h_EVERYTHING)) f1=h_MINE;
else f1=h_UNKNOWN;
}
feld[x][y]=f2 | f1;
/*if (f1==h_UNKNOWN)*/ return(p1 | p2);
}
char apermutate2(border_typ *border,int mine_anz)
{
char x,y;
char p1=p_IMPOSSIBLE,p2=p_IMPOSSIBLE,f1,f2;
if (border>=border_anz)
{
if (mines_left+fields_left-(border_anz-border_arr)>=mine_anz)
return p_POSSIBLE; else return p_IMPOSSIBLE;
}
x=border->x;y=border->y;
if (test_if_possible(border,XMAX,YMAX,feld))
p1=apermutate2(border+1,mine_anz);
if (mine_anz>0)
{
feld[x][y]|=MARK;
if (test_if_possible(border,XMAX,YMAX,feld)) p2=apermutate2(border+1,mine_anz-1);
feld[x][y]&=~MARK;
}
f1=feld[x][y] & h_MASK;f2=feld[x][y] & ~h_MASK;
if (p1==p_POSSIBLE)
{
if ((f1==h_NOMINE) || (f1==h_EVERYTHING)) f1=h_NOMINE;
else f1=h_UNKNOWN;
}
if (p2==p_POSSIBLE)
{
if ((f1==h_MINE) || (f1==h_EVERYTHING)) f1=h_MINE;
else f1=h_UNKNOWN;
}
feld[x][y]=f2 | f1;
/*if (f1==h_UNKNOWN)*/ return(p1 | p2);
}
int set_mark(int x,int y)
{
if (!(feld[x][y] & CLOSED)) {ende=TRUE;err=NOT_CLOSED;return TRUE;};
if (feld[x][y] & MARK) return FALSE;/*{ende=TRUE;err=MARK_SET;return TRUE;};*/
if (!(feld[x][y] & MINE)) {ende=TRUE;err=NO_MINE;return TRUE;};
if (mines_left==0) {ende=TRUE;err=MINES_LEFT;return TRUE;};
feld[x][y]|=MARK;mines_left-=1;return FALSE;
}
int hint_debug(void)
{
border_typ *border;
for (border=border_arr;border<border_anz;border++)
{
int d=feld[border->x][border->y];
if ((((d & h_MASK)==h_NOMINE) && (d & MINE)) ||
(((d & h_MASK)==h_MINE) && !(d & MINE)))
{err=HINT_DEBUG;ende=TRUE;return TRUE;};
}
return FALSE;
}
void add_time(int t) {time_c+=t;}
void add_timea(int t) {time_a+=t;}
void inc(int *p) {*p+=1;}
void add(int *p,int x) {*p+=x;}
/* ein Hinweis */
int hint_it(void)
{
char x,y,p=0,domain;
int closed_fields_without_border,max_mines,min_mines;
border_typ *border,*ptr;
/* Suche nach einem falschen Zug */
for (x=0;x<XMAX;x++)
for (y=0;y<YMAX;y++)
if (move_wrong(x,y))
{
ende=TRUE;err=WRONG;return TRUE;
}
/* Suche nach einem offensichtlichen Zug */
for (x=0;x<XMAX;x++)
for (y=0;y<YMAX;y++)
if (move_obvious(x,y))
{
ende=TRUE;err=OBVIOUS;return TRUE;
}
/* Suche nach einer eindeutigen Schlussfolgerung */
init_border();
if (border_anz==border_arr) {exit_border();blotch();return TRUE;};
border=border_arr;domain=1;max_mines=0;min_mines=0;
do {
if (max(domain)==INT_MIN)
{
int t;
for (ptr=border;ptr->domain==domain;ptr++)
feld[ptr->x][ptr->y]&=~h_MASK;
s=0;t=clock();
permutate1(border,0,domain);
add_time(clock()-t);inc(&freq[ptr-border]);
add(&steps[ptr-border],s);
for (ptr=border;ptr->domain==domain;ptr++)
feld[ptr->x][ptr->y]&=~h_MASK;
t=clock();
apermutate1(border,0,domain);
add_timea(clock()-t);
}
max_mines+=max(domain);min_mines+=min(domain);
while ((border->domain==domain) && (border<border_anz)) border++;
domain++;
} while (border<border_anz);
closed_fields_without_border=mines_left+fields_left - (border_anz-border_arr);
if (closed_fields_without_border<0)
{ ende=TRUE;err=NEG_REST_FIELDS;return TRUE;}
{
int t;
for (ptr=border_arr;ptr<border_anz;ptr++)
feld[ptr->x][ptr->y]&=~h_MASK;
s=0;t=clock();
permutate2(border_arr,mines_left);
add_time(clock()-t);inc(&freq_o[border_anz-border_arr]);
add(&steps_o[border_anz-border_arr],s);
for (ptr=border_arr;ptr<border_anz;ptr++)
feld[ptr->x][ptr->y]&=~h_MASK;
t=clock();
apermutate2(border_arr,mines_left);
add_timea(clock()-t);
if ((max_mines>mines_left) ||
(closed_fields_without_border<mines_left-min_mines))
if (max_mines>mines_left) max_mines=mines_left;
}
if (closed_fields_without_border>0)
{
if (min_mines==mines_left)
{
int do_it=TRUE;
for (x=0;x<XMAX;x++) for (y=0;y<YMAX;y++)
{
for (ptr=border_arr;ptr<border_anz;ptr++)
if ((ptr->x==x) && (ptr->y==y)) do_it=FALSE;
if (do_it) open_field(ptr->x,ptr->y);
}
}
if (closed_fields_without_border==mines_left-max_mines)
for (x=0;x<XMAX;x++) for (y=0;y<YMAX;y++)
{
int do_it=TRUE;
for (ptr=border_arr;ptr<border_anz;ptr++)
if ((ptr->x==x) && (ptr->y==y)) do_it=FALSE;
if (do_it) if (set_mark(ptr->x,ptr->y)) return TRUE;
}
}
if (hint_debug()) return TRUE;
for (border=border_arr;border<border_anz;border++)
{
register unsigned char d=feld[border->x][border->y] & h_MASK;
if ((d==h_NOMINE) || (d==h_MINE)) p++;
}
if (p!=0) return FALSE;
border=&border_arr[rand() % (border_anz-border_arr)];
if (feld[border->x][border->y] & MINE)
set_mark(border->x,border->y);
else open_field(border->x,border->y);
exit_border();
return FALSE;
}
void play(void)
{
int x0,y0,change;
ende=FALSE;overflow=FALSE;err=FALSE;
do {
printf(".");
do {
change=FALSE;
for (x0=0;x0<XMAX;x0++)
for (y0=0;y0<YMAX;y0++)
if (!(feld[x0][y0] & CLOSED))
{
int mines=0,marks=0,unknown=0,d;
for (d=0;d<8;d++)
{
int x1=x0+off[d][0],y1=y0+off[d][1];
if (in_playground(x1,y1))
{
register char f=feld[x1][y1];
if (f & CLOSED) {if (f & MARK) marks++; else unknown++;};
if (f & MINE) mines++;
}
}
if ((unknown!=0) && (marks==mines))
{
for (d=0;d<8;d++)
{
int x1=x0+off[d][0],y1=y0+off[d][1];
if ((in_playground(x1,y1)) && (feld[x1][y1] & CLOSED) && (!(feld[x1][y1] & MARK)))
{
open_field(x1,y1);
change=TRUE;
}
}
}
if ((unknown!=0) && (marks+unknown==mines))
{
for (d=0;d<8;d++)
{
int x1=x0+off[d][0],y1=y0+off[d][1];
if ((in_playground(x1,y1)) && (!(feld[x1][y1] & MARK)) && (feld[x1][y1] & CLOSED))
{
if (set_mark(x1,y1))
{
int x2,y2;
for (y2=-1;y2<=1;y2++)
{
if (y2==0) printf("%2i ",x2-x0); else printf(" ");
for (x2=-1;x2<=1;x2++)
if (in_playground(x0+x2,y0+y2)) printf("%4i",feld[x0+x2][y0+y2]);
printf("\n");
}
return;
}
change=TRUE;
}
}
}
}
} while (change);
if (hint_it()) return;
for (x0=0;x0<XMAX;x0++)
for (y0=0;y0<YMAX;y0++)
{
if ((feld[x0][y0] & h_MASK)==h_MINE) if (set_mark(x0,y0)) return;
if ((feld[x0][y0] & h_MASK)==h_NOMINE) open_field(x0,y0);
}
if ((fields_left==0) || (mines_left==0)) ende=TRUE;
} while (!ende);
printf("\n");
}
void init_bench(void)
{
int i;
for (i=0;i<256;i++)
{
freq_o[i]=0;
steps_o[i]=0;
freq[i]=0;
steps[i]=0;
}
time_c=0;time_a=0;
}
char ext[2]="A";
void save(void)
{
FILE *f;
if (err)
{
printf("Error :%i\n",err);
if ((f=fopen("<Mines$Dir>.bencherr","ab"))==0) werr(TRUE,"File err");
fwrite(feld,XMAX*YMAX,sizeof(int),f);
fclose(f);
return;
}
if (overflow)
{
printf("Overflow");
rename("<Mines$Dir>.benchmark",strcat("<Mines$Dir>.benchmark",ext));
ext[0]+=1;
init_bench();
return;
}
if ((f=fopen("<Mines$Dir>.benchmark","wb"))==0) werr(TRUE,"File err");
fwrite(freq_o,256,sizeof(int),f);
fwrite(steps_o,256,sizeof(int),f);
fwrite(freq,256,sizeof(int),f);
fwrite(steps,256,sizeof(int),f);
fwrite(&time_c,1,sizeof(int),f);
fwrite(&time_a,1,sizeof(int),f);
fclose(f);
}
int main(void)
{
int x,y,c;
printf("init");
init_bench();
border_arr=malloc(XMAX*YMAX*sizeof(border_typ));
last_border_arr=malloc(XMAX*YMAX*sizeof(border_typ));
last_border_anz=last_border_arr;
minmax=malloc(256*sizeof(int));
lastminmax=malloc(256*sizeof(int));
printf("done\n");
do {
printf("res_feld\n");
res_feld();
printf("blotch\n");
blotch();
printf("play");
play();
printf("\n");
for (y=0;y<YMAX;y++)
{
for (x=0;x<XMAX;x++)
if (feld[x][y] & CLOSED)
{
if (feld[x][y] & MARK) printf("*"); else printf(".");
}
else
if ((c=count(x,y))==0) printf(" "); else printf("%i",c);
printf("\n");
}
printf("save\n");
save();
} while (TRUE);
return 0;
}